﻿import { useEffect, useMemo, useState, type CSSProperties } from 'react';
import { PDFDocument, rgb, StandardFonts, PDFName, PDFString } from 'pdf-lib';
import './TestPage.css';

type DeviceInfo = {
  index: number;
  label: string;
  sn: string;
};

type CertInfo = {
  subjectCN: string;
  issuerCN: string;
  serial: string;
  usageText: string;
  validFrom: string;
  validTo: string;
  algorithm: string;
};

const ensureZjcaReady = () => {
  if ((window as any).g_ZjcaCMT) return true;
  const ctor = (window as any).zjca_CMT;
  if (!ctor) return false;
  const attempt = (protocol: 'https' | 'http') => {
    try {
      const instance = new ctor(() => {}, null);
      instance.setProtocol(protocol);
      const resp = instance.init(1, 1);
      if (resp?.code === 0) {
        (window as any).g_ZjcaCMT = instance;
        return true;
      }
    } catch (error) {
      console.warn(`使用 ${protocol.toUpperCase()} 初始化 ZJCA 失败:`, error);
    }
    return false;
  };
  return attempt('https') || attempt('http');
};

const useZjcaReady = () => {
  const [ready, setReady] = useState(false);
  useEffect(() => {
    setReady(ensureZjcaReady());
  }, []);
  return ready;
};

const describeDevice = (key: any): DeviceInfo => ({
  index: typeof key.getIndex === 'function' ? key.getIndex() : key.index ?? -1,
  label: typeof key.getLabel === 'function' ? key.getLabel() : key.label ?? '未知介质',
  sn: typeof key.getSN === 'function' ? key.getSN() : key.sn ?? '',
});

const formatFileName = (path: string) => (path ? path.split(/[/\\]/).pop() || path : '');

const base64ToUint8Array = (base64: string) => {
  const binary = atob(base64);
  const length = binary.length;
  const bytes = new Uint8Array(length);
  for (let i = 0; i < length; i += 1) {
    bytes[i] = binary.charCodeAt(i);
  }
  return bytes;
};

const uint8ArrayToBase64 = (buffer: Uint8Array) => {
  const chunkSize = 8 * 1024;
  let binary = '';
  for (let i = 0; i < buffer.length; i += chunkSize) {
    const chunk = buffer.subarray(i, i + chunkSize);
    binary += String.fromCharCode(...chunk);
  }
  return btoa(binary);
};

const estimatePdfPageCount = (base64: string) => {
  try {
    if (typeof window === 'undefined' || !window.atob) return null;
    const binary = window.atob(base64);
    const matches = binary.match(/\/Type\s*\/Page\b/g);
    if (matches && matches.length > 0) {
      return matches.length;
    }
  } catch (error) {
    console.warn('解析 PDF 页数失败:', error);
  }
  return null;
};

const InlineSignaturePage = () => {
  const ready = useZjcaReady();
  const zjca = useMemo(() => (window as any).g_ZjcaCMT, [ready]);

  const [devices, setDevices] = useState<DeviceInfo[]>([]);
  const [deviceIndex, setDeviceIndex] = useState<number>(-1);
  const [statusHint, setStatusHint] = useState('正在检测 ZJCA 客户端...');

  const [pdfPath, setPdfPath] = useState('');
  const [pdfName, setPdfName] = useState('');
  const [pdfPreviewUrl, setPdfPreviewUrl] = useState('');
  const [pdfPageCount, setPdfPageCount] = useState<number | null>(null);
  const [signing, setSigning] = useState(false);
  const [lastSignedPath, setLastSignedPath] = useState('');

  const [signatureBase64, setSignatureBase64] = useState('');
  const [signatureTimestamp, setSignatureTimestamp] = useState('');
  const [signatureCertInfo, setSignatureCertInfo] = useState<CertInfo | null>(null);
  const [detailVisible, setDetailVisible] = useState(false);

  const [annotationText, setAnnotationText] = useState(
    'Signature anchor generated by ZJCA inline signing. Please verify contents before signing.',
  );
  const [buttonLabel, setButtonLabel] = useState('View Signature Details');
  const [buttonTooltip, setButtonTooltip] = useState('Open the embedded signature detail entry.');

  useEffect(() => {
    if (ready && zjca) {
      setStatusHint('✅ ZJCA 客户端已连接');
      loadDevices();
    } else {
      setStatusHint('⚠️ 未检测到 ZJCA 客户端，请返回首页初始化');
      setDevices([]);
      setDeviceIndex(-1);
    }
  }, [ready, zjca]);

  const loadDevices = () => {
    if (!zjca) return;
    try {
      const resp = zjca.getKeyList(false);
      if (resp?.code === 0 && Array.isArray(resp.res)) {
        const list = resp.res.map((key: any) => describeDevice(key));
        setDevices(list);
        setDeviceIndex((prev) =>
          prev >= 0 && list.some((item: DeviceInfo) => item.index === prev) ? prev : list[0]?.index ?? -1,
        );
      } else {
        setDevices([]);
        setDeviceIndex(-1);
      }
    } catch (error) {
      console.warn('枚举介质失败:', error);
      setDevices([]);
      setDeviceIndex(-1);
    }
  };

  const decodeCertInfo = (certBase64: string): CertInfo | null => {
    if (!zjca || !certBase64) return null;
    let handle: any = null;
    try {
      const resp = zjca.decodeCert(certBase64);
      if (resp?.code !== 0 || !resp.res) return null;
      handle = resp.res;
      const getAttr = (key: string, param = '') => {
        const attr = zjca.getCertAttribute(handle, key, param);
        return attr?.code === 0 ? attr.res : '';
      };
      const usage = Number(getAttr('cert_usage'));
      const usageText = usage === 1 ? '签名' : usage === 2 ? '加密' : '未知';
      const valid = zjca.getCertAttribute(handle, 'cert_validdate', '')?.res;
      const alg = Number(getAttr('cert_keyalg'));
      let algorithm = '未知';
      if (alg === 1) algorithm = 'RSA';
      else if (alg === 2) algorithm = 'SM2 (国密)';
      return {
        subjectCN: getAttr('cert_subject', 'CN=') || getAttr('cert_subject') || '未知',
        issuerCN: getAttr('cert_issuer', 'CN=') || getAttr('cert_issuer') || '未知',
        serial: getAttr('cert_sn') || '未知',
        usageText,
        validFrom: valid?.fromDate || '未知',
        validTo: valid?.endDate || '未知',
        algorithm,
      };
    } catch (error) {
      console.warn('解析证书失败:', error);
      return null;
    } finally {
      if (handle) {
        try {
          zjca.releaseCert(handle);
        } catch (releaseError) {
          console.warn('释放证书句柄失败:', releaseError);
        }
      }
    }
  };

  const loadSignatureSummary = (path: string, base64?: string) => {
    if (!zjca || !path) return;
    try {
      let content = base64;
      if (!content) {
        const resp = zjca.readFile(path, true);
        if (resp?.code !== 0 || !resp.res) {
          throw new Error(resp?.msg || '读取签名文件失败');
        }
        content = resp.res as string;
      }
      setSignatureBase64(content);
      const attached = zjca.getSignatureAttached(content);
      if (attached?.code === 0 && attached.res) {
        setSignatureTimestamp(attached.res.time || '');
        setSignatureCertInfo(attached.res.cert ? decodeCertInfo(attached.res.cert) : null);
      } else {
        setSignatureTimestamp('');
        setSignatureCertInfo(null);
      }
    } catch (error) {
      console.warn('解析签名文件失败:', error);
      setSignatureBase64('');
      setSignatureTimestamp('');
      setSignatureCertInfo(null);
    }
  };

  const browsePdf = () => {
    if (!ready || !zjca) {
      alert('ZJCA 客户端未初始化，请返回首页完成初始化');
      return;
    }
    const resp = zjca.getFileName(true, '选择需要签名的 PDF 文件', '*.pdf');
    if (resp?.code === 0 && resp.res) {
      const path = resp.res as string;
      setPdfPath(path);
      setPdfName(formatFileName(path));
      try {
        const readResp = zjca.readFile(path, true);
        if (readResp?.code === 0 && readResp.res) {
          const base64 = readResp.res as string;
          setPdfPreviewUrl(`data:application/pdf;base64,${base64}`);
          setPdfPageCount(estimatePdfPageCount(base64));
        } else {
          setPdfPreviewUrl('');
          setPdfPageCount(null);
          console.warn('读取 PDF 预览失败:', readResp?.msg);
        }
      } catch (error) {
        setPdfPreviewUrl('');
        setPdfPageCount(null);
        console.warn('读取 PDF 预览失败:', error);
      }
    }
  };

  const preprocessPdfBeforeSign = async (path: string) => {
    if (!zjca) throw new Error('ZJCA 客户端未初始化');
    const readResp = zjca.readFile(path, true);
    if (readResp?.code !== 0 || !readResp.res) {
      throw new Error(readResp?.msg || '读取 PDF 失败');
    }

    const pdfBytes = base64ToUint8Array(readResp.res as string);
    const pdfDoc = await PDFDocument.load(pdfBytes);
    const pages = pdfDoc.getPages();
    if (!pages.length) throw new Error('PDF 文件为空，无法添加注释');

    const page = pages[0];
    const { width, height } = page.getSize();
    const font = await pdfDoc.embedFont(StandardFonts.HelveticaBold);

    const textValue =
      annotationText?.trim() ||
      'Signature anchor generated by ZJCA inline signing. Please verify contents before signing.';
    const infoLines = textValue
      .replace(/\r/g, '')
      .split('\n')
      .map((line) => line.trim())
      .filter((line) => line.length > 0)
      .flatMap((line) => {
        if (line.length <= 36) return [line];
        const chunks: string[] = [];
        for (let start = 0; start < line.length; start += 36) {
          chunks.push(line.slice(start, start + 36));
        }
        return chunks;
      });
    const fallbackLines = infoLines.length ? infoLines : ['Inline signing anchor'];
    const infoBoxWidth = 230;
    const infoBoxHeight = 32 + fallbackLines.length * 12;
    const infoBoxX = Math.max(24, width - infoBoxWidth - 24);
    const infoBoxY = Math.max(24, height - infoBoxHeight - 80);

    page.drawRectangle({
      x: infoBoxX,
      y: infoBoxY,
      width: infoBoxWidth,
      height: infoBoxHeight,
      borderColor: rgb(0.95, 0.3, 0.2),
      color: rgb(1, 0.93, 0.8),
      borderWidth: 1.2,
      opacity: 0.95,
    });

    let currentY = infoBoxY + infoBoxHeight - 18;
    fallbackLines.forEach((line) => {
      page.drawText(line, {
        x: infoBoxX + 12,
        y: currentY,
        font,
        size: 11,
        color: rgb(0.35, 0.2, 0.1),
      });
      currentY -= 12;
    });
    page.drawText(`Prepared: ${new Date().toLocaleString()}`, {
      x: infoBoxX + 12,
      y: infoBoxY + 8,
      font,
      size: 8,
      color: rgb(0.4, 0.3, 0.2),
    });

    const buttonText = buttonLabel?.trim() || 'View Signature Details';
    const buttonWidth = 180;
    const buttonHeight = 32;
    let buttonX = Math.max(24, width - buttonWidth - 40);
    let buttonY = infoBoxY - buttonHeight - 16;
    if (buttonY < 24) {
      buttonY = infoBoxY + infoBoxHeight + 12;
    }
    const form = pdfDoc.getForm();
    const button = form.createButton('zjca.inline.detail.button');
    button.addToPage(buttonText, page, {
      x: buttonX,
      y: buttonY,
      width: buttonWidth,
      height: buttonHeight,
      textColor: rgb(1, 1, 1),
      backgroundColor: rgb(0.16, 0.38, 0.6),
      borderColor: rgb(1, 1, 1),
      borderWidth: 1.2,
      font,
    });
    const buttonDict = (button as any)?.acroField?.dict;
    if (buttonDict) {
      buttonDict.set(PDFName.of('T'), PDFString.of('zjca.inline.detail.button'));
      const tooltip = buttonTooltip?.trim();
      if (tooltip) {
        buttonDict.set(PDFName.of('TU'), PDFString.of(tooltip));
      }
    }

    const updatedBytes = await pdfDoc.save();
    const updatedBase64 = uint8ArrayToBase64(updatedBytes);
    let preparedPath = path.replace(/\.pdf$/i, '_prepared.pdf');
    if (preparedPath === path) {
      preparedPath = `${path}_prepared.pdf`;
    }
    const writeResp = zjca.writeFile(preparedPath, updatedBase64, true);
    if (writeResp?.code !== 0) {
      throw new Error(writeResp?.msg || '写入预处理 PDF 失败');
    }
    return preparedPath;
  };

  const handleInlineSign = async () => {
    if (!ready || !zjca) {
      alert('ZJCA 客户端未初始化，请返回首页完成初始化');
      return;
    }
    if (deviceIndex < 0) {
      alert('请先选择用于签名的介质');
      return;
    }
    if (!pdfPath) {
      alert('请选择需要签名的 PDF 文件');
      return;
    }
    if (!pdfPath.toLowerCase().endsWith('.pdf')) {
      alert('仅支持 .pdf 文件，请重新选择');
      return;
    }
    try {
      const pinResp = zjca.verifyPin(deviceIndex, '');
      if (pinResp?.code !== 0) {
        alert(`PIN 验证失败：${pinResp?.msg || pinResp?.code || '未知错误'}`);
        return;
      }
    } catch (error: any) {
      alert(`PIN 验证异常：${error?.message || error}`);
      return;
    }

    try {
      setSigning(true);
      const preparedPath = await preprocessPdfBeforeSign(pdfPath);
      const signResp = zjca.signFileUseKey(deviceIndex, 0, 2, 0x07, preparedPath, null, null);
      if (!signResp || signResp.code !== 0 || !signResp.res) {
        alert(`内嵌签名失败：${signResp?.msg || '未知错误'}`);
        return;
      }
      const suggest = `${(pdfName || 'signed').replace(/\.pdf$/i, '')}.p7m`;
      const saveResp = zjca.getFileName(false, `保存内嵌签名文件（建议：${suggest}）`, '*.p7m');
      if (saveResp?.code !== 0 || !saveResp.res) return;
      let targetPath = saveResp.res as string;
      if (!targetPath.toLowerCase().endsWith('.p7m')) {
        targetPath = `${targetPath}.p7m`;
      }
      const writeResp = zjca.writeFile(targetPath, signResp.res, true);
      if (writeResp?.code !== 0) {
        alert(`写入签名文件失败：${writeResp?.msg || '未知错误'}`);
        return;
      }
      setLastSignedPath(targetPath);
      loadSignatureSummary(targetPath, signResp.res as string);
      setDetailVisible(true);
      alert(`内嵌式签名成功！\n保存路径：${targetPath}`);
    } catch (error: any) {
      alert(`内嵌签名异常：${error?.message || error}`);
    } finally {
      setSigning(false);
    }
  };

  const browseExistingSignature = () => {
    if (!zjca) return;
    const resp = zjca.getFileName(true, '选择内嵌签名文件 (.p7m/.p7s)', '*.p7m;*.p7s');
    if (resp?.code === 0 && resp.res) {
      setLastSignedPath(resp.res as string);
      loadSignatureSummary(resp.res as string);
      setDetailVisible(true);
    }
  };

  const detailBlock = () => {
    if (!detailVisible || (!signatureBase64 && !signatureCertInfo)) {
      return (
        <div style={{ color: '#9ca3af', fontSize: 13 }}>
          生成签名或选择现有内嵌签名文件后，可查看详细信息。
        </div>
      );
    }
    return (
      <div
        style={{
          marginTop: 12,
          padding: 16,
          borderRadius: 16,
          border: '1px solid #c7d2fe',
          background: '#eef2ff',
          color: '#111827',
          lineHeight: 1.7,
        }}
      >
        {lastSignedPath && <div>签名文件：{lastSignedPath}</div>}
        {signatureTimestamp && <div>签名时间：{signatureTimestamp}</div>}
        {signatureCertInfo ? (
          <>
            <div>证书主题：{signatureCertInfo.subjectCN}</div>
            <div>颁发者：{signatureCertInfo.issuerCN}</div>
            <div>序列号：{signatureCertInfo.serial}</div>
            <div>
              用途：{signatureCertInfo.usageText} | 算法：{signatureCertInfo.algorithm}
            </div>
            <div>
              有效期：{signatureCertInfo.validFrom} - {signatureCertInfo.validTo}
            </div>
          </>
        ) : (
          <div>未从签名文件中读取到证书信息。</div>
        )}
        <p style={{ color: '#6b7280', fontSize: 12, marginTop: 10 }}>
          说明：.p7m 文件中已包含 PDF 原文与证书，可直接打开或发送给其他方进行验签。
        </p>
      </div>
    );
  };

  const panelStyle: CSSProperties = {
    padding: 24,
    borderRadius: 24,
    background: '#fff',
    boxShadow: '0 18px 40px rgba(0,0,0,0.15)',
    marginBottom: 24,
  };

  const buttonStyle = (enabled: boolean, color: string): CSSProperties => ({
    padding: '10px 22px',
    borderRadius: 20,
    border: 'none',
    color: '#fff',
    fontWeight: 600,
    cursor: enabled ? 'pointer' : 'not-allowed',
    opacity: enabled ? 1 : 0.45,
    background: color,
    boxShadow: enabled ? `0 6px 18px ${color}33` : 'none',
  });

  const renderDeviceSelector = () => (
    <div
      style={{
        marginBottom: 16,
        padding: 12,
        borderRadius: 12,
        background: '#eef2ff',
        display: 'flex',
        flexWrap: 'wrap',
        gap: 12,
        alignItems: 'center',
      }}
    >
      <span style={{ fontWeight: 600, color: '#1e3a8a' }}>签名介质</span>
      <select
        value={deviceIndex >= 0 ? deviceIndex : ''}
        onChange={(e) => setDeviceIndex(Number(e.target.value))}
        style={{ minWidth: 240, padding: '8px 12px', borderRadius: 8 }}
      >
        {devices.length === 0 && <option value="">未检测到介质</option>}
        {devices.length > 0 && <option value="">请选择介质</option>}
        {devices.map((device) => (
          <option key={device.index} value={device.index}>
            {device.label}
            {device.sn ? ` (${device.sn})` : ''}
          </option>
        ))}
      </select>
      <button type="button" style={buttonStyle(true, '#6366f1')} onClick={loadDevices}>
        刷新介质
      </button>
    </div>
  );

  return (
    <div
      className="test-page"
      style={{ minHeight: '100vh', background: 'linear-gradient(135deg,#5c6bc0,#1e88e5)', padding: 24 }}
    >
      <div
        className="test-container"
        style={{
          maxWidth: 820,
          margin: '0 auto',
          background: 'rgba(255,255,255,0.97)',
          borderRadius: 30,
          padding: 32,
          boxShadow: '0 26px 70px rgba(0,0,0,0.25)',
        }}
      >
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <h2>🧾 内嵌式签名（PDF）</h2>
          <span
            style={{
              padding: '6px 16px',
              borderRadius: 999,
              background: ready ? '#22c55e' : '#f97316',
              color: '#fff',
              fontWeight: 600,
            }}
          >
            {statusHint}
          </span>
        </div>
        <div style={panelStyle}>
          <h3>1. 选择 PDF 并生成内嵌签名</h3>
          <p style={{ color: '#4b5563' }}>
            生成的 .p7m 文件中包含原始 PDF、证书及时间戳，可直接打开查看或发送给其他单位验签。
          </p>
          {renderDeviceSelector()}
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginBottom: 12 }}>
            <button style={buttonStyle(ready, '#1d4ed8')} disabled={!ready} onClick={browsePdf}>
              选择 PDF
            </button>
            <button
              style={buttonStyle(ready && !!pdfPath && !signing && deviceIndex >= 0, '#ec4899')}
              disabled={!ready || !pdfPath || signing || deviceIndex < 0}
              onClick={handleInlineSign}
            >
              {signing ? '签名中...' : '生成内嵌签名'}
            </button>
          </div>
          <div
            style={{
              display: 'grid',
              gridTemplateColumns: 'repeat(auto-fit,minmax(260px,1fr))',
              gap: 12,
              marginTop: 12,
            }}
          >
            <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 13, color: '#1f2937' }}>
              预处理提示文字
              <textarea
                value={annotationText}
                onChange={(e) => setAnnotationText(e.target.value)}
                style={{ minHeight: 96, borderRadius: 10, padding: 10, border: '1px solid #d1d5db', fontSize: 13 }}
                placeholder="在签名前写入 PDF 的提示内容（建议使用英文字母或数字）"
              />
            </label>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 13, color: '#1f2937' }}>
                按钮文字
                <input
                  value={buttonLabel}
                  onChange={(e) => setButtonLabel(e.target.value)}
                  style={{ borderRadius: 10, padding: '10px 14px', border: '1px solid #d1d5db', fontSize: 13 }}
                  placeholder="例如：View Signature Details"
                />
              </label>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 13, color: '#1f2937' }}>
                按钮提示（鼠标悬停显示）
                <input
                  value={buttonTooltip}
                  onChange={(e) => setButtonTooltip(e.target.value)}
                  style={{ borderRadius: 10, padding: '10px 14px', border: '1px solid #d1d5db', fontSize: 13 }}
                  placeholder="tooltip 文案，可为空"
                />
              </label>
              <span style={{ fontSize: 12, color: '#6b7280' }}>
                说明：浏览器预处理阶段使用内置 Helvetica 字体，暂不支持直接渲染中文字符，建议使用英文或数字提示。
              </span>
            </div>
          </div>
          {pdfName && <div style={{ color: '#1f2937', fontSize: 13 }}>已选择：{pdfName}</div>}
          {lastSignedPath && (
            <div style={{ marginTop: 8, color: '#15803d', fontSize: 13 }}>最近签名：{lastSignedPath}</div>
          )}
        </div>

        <div style={panelStyle}>
          <h3>2. 查看或载入已有内嵌签名</h3>
          <p style={{ color: '#4b5563' }}>
            可直接载入已有的 .p7m/.p7s 文件查看签名详情，便于核对证书及时间戳信息。
          </p>
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
            <button style={buttonStyle(true, '#7c3aed')} onClick={browseExistingSignature}>
              选择 .p7m/.p7s 文件
            </button>
          </div>
          {pdfPreviewUrl ? (
            <div style={{ marginTop: 16, position: 'relative' }}>
              <div style={{ fontWeight: 600, marginBottom: 8 }}>
                PDF 预览
                {pdfPageCount != null && (
                  <span style={{ marginLeft: 8, color: '#6b7280', fontSize: 13 }}>
                    页数：{pdfPageCount}
                  </span>
                )}
              </div>
              <object
                data={pdfPreviewUrl}
                type="application/pdf"
                width="100%"
                height="480"
                style={{ border: '1px solid #e5e7eb', borderRadius: 12 }}
              >
                <p style={{ padding: 12, color: '#6b7280' }}>
                  浏览器无法直接预览该 PDF，可点击“生成内嵌签名”后在 .p7m 文件中查看。
                </p>
              </object>
              <div
                style={{
                  position: 'absolute',
                  bottom: 16,
                  right: 16,
                  display: 'flex',
                  flexDirection: 'column',
                  alignItems: 'flex-end',
                  gap: 6,
                }}
              >
                <button
                  style={{
                    padding: '10px 18px',
                    borderRadius: 999,
                    border: 'none',
                    background: lastSignedPath || signatureBase64 ? '#f97316' : '#d1d5db',
                    color: '#fff',
                    fontWeight: 600,
                    cursor: lastSignedPath || signatureBase64 ? 'pointer' : 'not-allowed',
                    boxShadow: '0 4px 12px rgba(0,0,0,0.2)',
                  }}
                  onClick={() => {
                    if (!lastSignedPath && !signatureBase64) {
                      alert('请先生成或选择签名文件');
                      return;
                    }
                    setDetailVisible((prev) => !prev);
                  }}
                >
                  {detailVisible ? '隐藏签名详情' : '查看签名详情'}
                </button>
                <span style={{ fontSize: 12, color: '#6b7280' }}>
                  点击按钮即可查看签名证书与介质信息。
                </span>
              </div>
            </div>
          ) : (
            <div style={{ marginTop: 16, color: '#9ca3af', fontSize: 13 }}>
              选择 PDF 后即可在此预览文件内容。
            </div>
          )}
          {detailVisible && detailBlock()}
        </div>
      </div>
    </div>
  );
};

export default InlineSignaturePage;
